#include <iostream>
#include <fstream>
#include <sstream>
#include "glCanvas.h"


//#include "../../src/core/InterpolationExacte.h"
//#include "../../src/core/InterpolationLineaire.h"
//#include "liblut/core/Interpolation.h"

GLData m_gldata;
/*--------------------------------------------------------------------------*/
/*   Création d'un canvas OpenGl                                            */
/*--------------------------------------------------------------------------*/
glCanvas::glCanvas(wxString nomfichier,int attr,eLutColorSpace syst,int type,
                   std::vector<LutBound*> vect,wxWindow *parent, wxWindowID id,
                   const wxPoint& pos, const wxSize& size, long style,
                   const wxString& name)
    : wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size,
                 style|wxFULL_REPAINT_ON_RESIZE , name )
{
    SetCurrent();
    rottest = false;
    // initialize view matrix
    m_gldata.beginx = 0.0f;
    m_gldata.beginy = 0.0f;
    m_gldata.zoom   = 45.0f;
    trackball(m_gldata.quat, 0.0f, 0.0f, 0.0f, 0.0f);
    loadasciifilename_OGL = nomfichier;
    AttributLut = attr;
    systemeCouleur_OGL = syst;
    typeinterp = type;
    lut = vect;
    //lecture du fichier ascii contenant les points à afficher
    ImportAscii(loadasciifilename_OGL);
    //calcul des minima pour chaque données: X,Y,Z,intensité, classe
    Barycentre();
    MinMaxX();
    MinMaxY();
    MinMaxZ();
    MinMaxI();
    MinMaxCl();
    //les x,y,z sont "recadrés" dans un cube , x,y appartient à [-1;1]*[-1;1]
    // et z<1
    IntervalleAffichage();
    //on stocke dans un vecteur pour chaque point, la borne de la lut
    //dont la valeur est immédiatement inférieure à  la valeur de
    // l'attribut du point
    AffectationIdBorne();
    //pour chaque point, on calcule la couleur associée
    //(calcul de l'interpolation) et on le stocke dans un vecteur
    AffectationCouleur();
    std::cout<<"maxz "<<maxZ<<std::endl;
    //FabriqueListe();
    angle = 0;
    transz = -1100;
}

/*--------------------------------------------------------------------------*/
/*           Création d'un canevas OpenGl  vide                             */
/*--------------------------------------------------------------------------*/
glCanvas::glCanvas(wxWindow *parent, wxWindowID id,
    const wxPoint& pos, const wxSize& size, long style, const wxString& name)
    : wxGLCanvas(parent, (wxGLCanvas*) NULL, id, pos, size,
                 style|wxFULL_REPAINT_ON_RESIZE , name )
{
    SetCurrent();
    rottest = false;
    // initialize view matrix
    m_gldata.beginx = 0.0f;
    m_gldata.beginy = 0.0f;
    m_gldata.zoom   = 45.0f;
    trackball(m_gldata.quat, 0.0f, 0.0f, 0.0f, 0.0f);
    angle = 0;
    transz = -1100;
    std::cout<<" glCanvas end empty init "<<std::endl;
}

/*---------------------------------------------------------------------------*/
/*           Destructeur par défault d'un canevas OpenGl                     */
/*---------------------------------------------------------------------------*/
glCanvas::~glCanvas()
{
}

void glCanvas::FabriqueListe()
{
    std::cout<<"entre fabriqueliste"<<std::endl;
    //definit la taille des points + dessine les points
    //(chaque point a une couleur)
    glPointSize(2);
    liste = glGenLists(1);
    glNewList(liste, GL_COMPILE);
    glBegin(GL_POINTS);
        glVertex3f(0.0, 0.0,0.0);
        glVertex3f(1.0, 0.0,0.0);
        glVertex3f(-1.0, 0.0,0.0);
        glVertex3f(0.0, 1.0,0.0);
        glVertex3f(0.0, -1.0,0.0);
        for(int C19 = 0; C19<donnees_ascii_affichage.size();C19++)
        {
            glColor3d((double)(couleurPoint[C19]->getC1() )/255,
                    (double)(couleurPoint[C19]->getC2() )/255,
                    (double)(couleurPoint[C19]->getC3() )/255);
    /*    glVertex3d(lecture_ascii[C19]->m_X,
                    lecture_ascii[C19]->m_Y,
                    lecture_ascii[C19]->m_Z);*/
            glVertex3d(donnees_ascii_affichage[C19]->m_X,
                    donnees_ascii_affichage[C19]->m_Y,
                    donnees_ascii_affichage[C19]->m_Z);
        }
    glEnd();
    glEndList();
    std::cout<<"sort fabrique liste"<<std::endl;
}

/*--------------------------------------------------------------------------*/
/*       Dessin des données dans le canevas OpenGL                          */
/*--------------------------------------------------------------------------*/
/* Description : on défini la zone de dessin (toute la fenetre OpenGL)      */
/*        on nettoie le Buffer dans lequel on va dessiner                   */
/*        on dessine les points:                                            */
/*           * on leur affecte une couleur en fonction de la lut            */
/*           * et une taille (la mÃªme pour tous les points)                */
/*--------------------------------------------------------------------------*/
void glCanvas::OnPaint( wxPaintEvent& WXUNUSED(event) )
{
    std::cout<<" OnPaint "<<std::endl;
    wxPaintDC dc(this);
    SetCurrent();

    Redimensionnement();

    // Clear le buffet courant
    glClearColor( 0.3f, 0.4f, 0.6f, 1.0f );
    glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
    std::cout<<"rottest onpaint  "<<rottest<<std::endl;
   // glPushMatrix();
    //glCallList(liste);
/*    if(rottest)
    {
        std::cout<<"test bool bis"<<rottest<<std::endl;
        std::cout<<"fleche gauche"<<std::endl;
        glRotatef( 45.0, 1.0f, 0.0f, 0.0f );

    }*/
   // glRotatef( xrot, 1.0f, 0.0f, 0.0f );
    glLoadIdentity();
    //glScalef(1.0,1.0,transz);
    glTranslatef( 0.0f , 0.0f,transz );
    //glRotatef( angle, 1.0f, 0.0f, 0.0f );
    GLfloat m[4][4];
    build_rotmatrix( m, m_gldata.quat );
    glMultMatrixf( &m[0][0] );

    //definit la taille des points
    // + dessine les points (chaque point a une couleur)
    glPointSize(3);
    glBegin(GL_POINTS);
        glVertex3f(0.0, 0.0,0.0);
        glVertex3f(10.0, 0.0,0.0);
        glVertex3f(-10.0, 0.0,0.0);
        glVertex3f(0.0, 10.0,0.0);
        glVertex3f(0.0, -10.0,0.0);
        for(int C19 = 0; C19<donnees_ascii_affichage.size();C19++)
        {
            glColor3d((double)(couleurPoint[C19]->getC1() )/255,
                    (double)(couleurPoint[C19]->getC2() )/255,
                    (double)(couleurPoint[C19]->getC3() )/255);
            glVertex3d(donnees_ascii_affichage[C19]->m_X,
                    donnees_ascii_affichage[C19]->m_Y,
                    donnees_ascii_affichage[C19]->m_Z);
        }
    glEnd();
    //glPopMatrix();
    rottest = false;


    glFlush();
    // Echage les 2 buffers: les points s'affichent à  l'écran
    SwapBuffers();
}


void glCanvas::OnMouse(wxMouseEvent& event)
{
    if (event.Dragging())
    {
/*    	if(event.RightDown())
        {*/
        wxSize sz(GetClientSize());

        /* drag in progress, simulate trackball */
        float spin_quat[4];
        trackball(spin_quat,
            (2.0*m_gldata.beginx - sz.x) / sz.x,
            (sz.y - 2.0*m_gldata.beginy) / sz.y,
            (2.0*event.GetX() - sz.x)    / sz.x,
            (sz.y - 2.0*event.GetY())    / sz.y);

        add_quats(spin_quat, m_gldata.quat, m_gldata.quat);

        /* orientation has changed, redraw mesh */
        Refresh(false);
    //	}
    }


    m_gldata.beginx = event.GetX();
    m_gldata.beginy = event.GetY();
    event.Skip();
}
/*--------------------------------------------------------------------------*/
/*         La taille de la fenetre a été modifiée                           */
/*--------------------------------------------------------------------------*/
void glCanvas::OnSize(wxSizeEvent& event)
{
    std::cout<<" OnSize "<<std::endl;
    wxGLCanvas::OnSize(event);
}

/*--------------------------------------------------------------------------*/
/*          La taille de la fenetre ayant été modifiée,                     */
/*          il faut modifier de même la taille du canves openGl             */
/*--------------------------------------------------------------------------*/
void glCanvas::Redimensionnement()
{
    int w, h;
    GetClientSize(&w, &h);
  //  if(!IsShown()) return;
    glViewport(0, 0, (GLint) w, (GLint) h);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluPerspective(25.0f, (GLfloat)w/h, 1.0, 2000.0);
    glMatrixMode(GL_MODELVIEW);
}


void glCanvas::OnChar(wxKeyEvent& event)
{
    std::cout<<"onchar"<<std::endl;
    switch( event.GetKeyCode() )
    {
/*    case WXK_LEFT:
        angle += 10;
        std::cout<<"angle test  "<<angle<<std::endl;
        Refresh(false);
        break;

    case WXK_RIGHT:
        angle -= 10;
        std::cout<<"angle test  "<<angle<<std::endl;
        Refresh(false);
        break;*/

    case 'p':
        transz += 50;
        std::cout<<"translation z test  "<<transz<<std::endl;
        //Refresh(false);
        break;

    case 'P':
        transz -= 50;
        std::cout<<"translation x test  "<<transz<<std::endl;

        break;
    }
    Refresh(false);
}

/*--------------------------------------------------------------------------*/
/*     Lecture d'un fichier ASCII et stockage des données                   */
/*--------------------------------------------------------------------------*/
/* Description : ouverture du fichier                                       */
/*     on lit ligne par ligne et on stocke les informations dans un vecteur */
/*--------------------------------------------------------------------------*/
void glCanvas::ImportAscii(wxString lfilename)
{
    std::cout<<"import fichier ascii"<<std::endl;
    std::string str_filename =  std::string(lfilename.mb_str());
    std::ifstream fichier(str_filename.c_str(), std::ios::in);
    //ouverture du fichier
    if(fichier)
    {
        std::string contenu;
        while(getline(fichier, contenu))  // on met dans "contenu" la ligne
        {
            //stockage des informations lues dans une structure associées
            //pour chaque ligne une DonneesAscii est crée
            //elle permet de stocker : x,y,z,intensité,classe
             std::istringstream entree(contenu);
             double x,y,z,i;
             int cl;
             entree>>x>>y>>z>>i>>cl;
             DonneesAscii *ligne = new DonneesAscii(x,y,z,i,cl);
             lecture_ascii.push_back(ligne);
        }
         fichier.close();  // fermeture du fichier
    }
    else
    {
        std::cerr <<"Erreur à l'ouverture !"<<std::endl;
    }
}

/*---------------------------------------------------------------------------*/
/*   Calcule les min et le max de x et les stocke dans minX et maxX          */
/*------------------------------------------------- -------------------------*/
void glCanvas::MinMaxX(){
    minX = lecture_ascii[0]->m_X;
    maxX = lecture_ascii[0]->m_X;
    for(int C18 = 1; C18<lecture_ascii.size();C18++)
    {
        if(lecture_ascii[C18]->m_X < minX)
        {
            minX = lecture_ascii[C18]->m_X;
        }
        if(lecture_ascii[C18]->m_X > maxX)
        {
            maxX = lecture_ascii[C18]->m_X;
        }
    }
}

/*--------------------------------------------------------------------------*/
/*     Calcule les min et le max de y et les stocke dans minY et maxY       */
/*--------------------------------------------------------------------------*/
void glCanvas::MinMaxY(){
    minY = lecture_ascii[0]->m_Y;
    maxY = lecture_ascii[0]->m_Y;
    for(int C18 = 1; C18<lecture_ascii.size();C18++)
    {
        if(lecture_ascii[C18]->m_Y < minY)
        {
            minY = lecture_ascii[C18]->m_Y;
        }
        if(lecture_ascii[C18]->m_Y > maxY)
        {
            maxY = lecture_ascii[C18]->m_Y;
        }
    }
}

/*--------------------------------------------------------------------------*/
/*       Calcule les min et le max de z et les stocke dans minZ et maxZ     */
/*----------------------------------------------------------- --------------*/
void glCanvas::MinMaxZ(){
    minZ = lecture_ascii[0]->m_Z;
    maxZ = lecture_ascii[0]->m_Z;
    for(int C18 = 1; C18<lecture_ascii.size();C18++)
    {
        if(lecture_ascii[C18]->m_Z < minZ)
        {
            minZ = lecture_ascii[C18]->m_Z;
        }
        if(lecture_ascii[C18]->m_Z > maxZ)
        {
            maxZ = lecture_ascii[C18]->m_Z;
        }
    }
}

/*---------------------------------------------------------------------------*/
/*  Calcule les min et le max de l'intensité et les stocke dans minI et maxI */
/*---------------------------------------------------------------------------*/
void glCanvas::MinMaxI(){
    minI = lecture_ascii[0]->m_I;
    maxI = lecture_ascii[0]->m_I;
    for(int C18 = 1; C18<lecture_ascii.size();C18++)
    {
        if(lecture_ascii[C18]->m_I < minI)
        {
            minI = lecture_ascii[C18]->m_I;
        }
        if(lecture_ascii[C18]->m_I > maxI)
        {
            maxI = lecture_ascii[C18]->m_I;
        }
    }
}

/*--------------------------------------------------------------------------*/
/* Calcule les min et le max de la classe et les stocke dans minCl et maxCl */
/*--------------------------------------------------------------------------*/
void glCanvas::MinMaxCl(){
    minCl = lecture_ascii[0]->m_Classe;
    maxCl = lecture_ascii[0]->m_Classe;
    for(int C18 = 1; C18<lecture_ascii.size();C18++)
    {
        if(lecture_ascii[C18]->m_Classe < minCl)
        {
            minCl = lecture_ascii[C18]->m_Classe;
        }
        if(lecture_ascii[C18]->m_Classe > maxCl)
        {
            maxCl = lecture_ascii[C18]->m_Classe;
        }
    }
}


void glCanvas::Barycentre(){
    barX = 0;
    barY = 0;
    barZ = 0;
    for(int C18 = 0; C18<lecture_ascii.size();C18++)
    {
        barX +=lecture_ascii[C18]->m_X/(double)lecture_ascii.size();
        barY +=lecture_ascii[C18]->m_Y/(double)lecture_ascii.size();
        barZ +=lecture_ascii[C18]->m_Z/(double)lecture_ascii.size();
    }
    std::cout<<"barX "<<barX<<std::endl;
}

/*--------------------------------------------------------------------------*/
/*       Recadre les intervalles de x,y,z dans [-1,1]*[-1,1]*[-1,1]         */
/*--------------------------------------------------------------------------*/
/* Description : copie les données pour ne modifier que le vecteur copie    */
/*                 et pas les valeurs brutes                                */
/*               recadre les valeurs pour faciliter l'affichage             */
/*--------------------------------------------------------------------------*/
void glCanvas::IntervalleAffichage()
{
    std::cout<<"entre dans intervalle affichage"<<std::endl;
    for (int C20 = 0;C20<lecture_ascii.size();C20++)
    {
        DonneesAscii *dTemp = new DonneesAscii(lecture_ascii[C20]->m_X,
                                                lecture_ascii[C20]->m_Y,
                                                lecture_ascii[C20]->m_Z,
                                                lecture_ascii[C20]->m_I,
                                                lecture_ascii[C20]->m_Classe);
         donnees_ascii_affichage.push_back(dTemp);
    }
/*	double aX = (double) (2/(maxX-minX));
    double bX = 1-aX*maxX;
    double aY = (double) (2/(maxY-minY));
    double bY = 1-aY*maxY;
    double aZ = (double) (2/(maxZ-minZ));
    double bZ = 1-aZ*maxZ;*/
    for(int C18 = 0; C18<lecture_ascii.size();C18++)
    {
        donnees_ascii_affichage[C18]->m_X =
                (double)(donnees_ascii_affichage[C18]->m_X-barX);
        donnees_ascii_affichage[C18]->m_Y =
                (double)(donnees_ascii_affichage[C18]->m_Y-barY);
        donnees_ascii_affichage[C18]->m_Z =
                (double)(donnees_ascii_affichage[C18]->m_Z-barZ);
    }
    std::cout<<"sort de intervalle affichage"<<std::endl;
}

/*--------------------------------------------------------------------------*/
/*   Crée un vecteur qui stocke pour chaque point la borne de la LUT        */
/*   dont la valeur est immédiatement inférieure à la valeur de l'attribut  */
/*--------------------------------------------------------------------------*/
/* Description : appelle CalculId(int),                                     */
/*         int en fonction de la nature de l'attribut                       */
/*--------------------------------------------------------------------------*/
void glCanvas::AffectationIdBorne()
{
    std::cout<<"entre dans affectation id borne"<<std::endl;
        switch(AttributLut)
        {
            case 0: //les données seront affectées sur l'altitude
            {
                CalculId(0);
            }
            break;
            case 1: //la lut sera affectée à l'intensité
            {
                CalculId(1);
            }
            break;
            case 2: // la lut sera affectée à la classe
            {
                CalculId(2);
            }
            break;
            default:
                wxMessageBox(_T("oups!!!"),
                    _T("About"), wxOK | wxICON_INFORMATION, this);
        }
    std::cout<<"sort de affectation id borne"<<std::endl;
}

/*--------------------------------------------------------------------------*/
/*       Calcule l'identifiant de la borne, appelé par AffecteId            */
/*--------------------------------------------------------------------------*/
/* Description : appelle CalculId(int)                                      */
/*              int en fonction de la nature de l'attribut                  */
/*--------------------------------------------------------------------------*/
void glCanvas::CalculId(int attribut)
{
    bool Taille;
    //parcours le vecteur lecture ascii pout affecter un identifiant
    // à chaque point
    for(int C19 = 0; C19<lecture_ascii.size();C19++)
    {
        Taille = true;
        int num = 0;
        //valeurAt: permet de stocker la valeur de l'attribut à chaque passage
        double valeurAt;
        double borneLut = (double) (lut[num]->getValue());
        if(attribut == 0)
        {
            valeurAt = (double) (lecture_ascii[C19]->m_Z);
        }
        else if(attribut == 1)
        {
            valeurAt = lecture_ascii[C19]->m_I;
        }
        else if(attribut == 2)
        {
            valeurAt = lecture_ascii[C19]->m_Classe;
        }
        //tant que la valeur de la borne est inférieure à la valeur de
        //l'attribut on continue à parcourir la lut
        while(borneLut < valeurAt && Taille )
        {
            //on compte le nombre de passage dans la boucle:
            //nous permet de connaitre l'identifiant de la borne
            //de la lut courante
            num++;
            //si on a atteint la taille de la lut,
            //il faut attribuer l'identifiant correspondant
            // à la dernière borne de la lut
            //et on sort de la boucle
            if(num == lut.size())
            {
                Taille = false;
            }
            else
            {
                borneLut =(double) (lut[num]->getValue());
            }
        }
        //on stocke tous les identifiants dans un vecteur
        //ce vecteur fera la même taille que lecture_ascii
        // (1 identifiant par point)
        numBorne.push_back(num);
    }
}

/*--------------------------------------------------------------------------*/
/*AffecteCouleur: affecte une couleur par point                             */
/*                et stocke ces couleurs dans un identifiant)               */
/*--------------------------------------------------------------------------*/
/* Description : pour chaque cas, calcule l'interpolation                   */
/*--------------------------------------------------------------------------*/
void glCanvas::AffectationCouleur()
{
    /*double position;
    std::cout<< "entre dans affectation couleur"<<std::endl;
    switch (typeinterp)
    {
    case 0:  //interpolation exacte
    {
        InterpolationExacte *interp = new InterpolationExacte();
        for(int C13 = 0;C13<donnees_ascii_affichage.size();C13++)
        {
            bool test = false;
            //appelle la fonction TestTypeCalcul
            test = TestTypeCalcul(C13,systemeCouleur_OGL);
            //en fonction de l'attribut (z, intensité ou classe),
            //calcule l'interpolation exacte
            if(AttributLut == 0)
            {
                interp->CalculInterpolation(systemeCouleur_OGL,
                        lut[numBorne[C13]-1],
                        lut[numBorne[C13]],
                        (int)donnees_ascii_affichage[C13]->m_Z);
            }
            else if(AttributLut == 1)
            {
                interp->CalculInterpolation(systemeCouleur_OGL,
                        lut[numBorne[C13]-1],
                        lut[numBorne[C13]],
                        (int)donnees_ascii_affichage[C13]->m_I);
            }
            else if(AttributLut == 2)
            {
                interp->CalculInterpolation(systemeCouleur_OGL,
                        lut[numBorne[C13]-1],
                        lut[numBorne[C13]],
                        (int)donnees_ascii_affichage[C13]->m_Classe);
            }
            //appelle la fonction AppliqueInterpolation
            // et stocke la couleur dans un vecteur
            couleurPoint.push_back(
                      AppliqueInterpolation(interp->i_R1,
                                            interp->i_V1,
                                            interp->i_B1,
                                           systemeCouleur_OGL));
            //voir TestTypeCalcul: on peux avoir rajouté un élément
            // en fin de lut
            //pour calculer l'interpolation des éléments dont l'attribut est
            //supérieur à la valeur de la dernière borne
            // => on le supprime avant de passer au point suivant (nettoyage)
            if(test)
            {
                lut.pop_back();
            }
        }
    }
    break;
    case 1://interpolation lineaire
    {
        std::cout<<"interpolation lineaire"<<std::endl;
        InterpolationLineaire *interpBis = new InterpolationLineaire();
        for(int C13 = 0;C13<donnees_ascii_affichage.size();C13++)
        {
            bool test = false;
            //appelle la fonction TestTypeCalcul
            test = TestTypeCalcul(C13,systemeCouleur_OGL);
            //en fonction de l'attribut (z, intensité ou classe),
            //calcule l'interpolation exacte
            if(AttributLut == 0)
            {
                position = (lecture_ascii[C13]->m_Z-minZ)/(maxZ-minZ);
                interpBis->CalculInterpolation(systemeCouleur_OGL,
                                        lut[numBorne[C13]-1],
                                        lut[numBorne[C13]],
                                        position);
            }
            else if(AttributLut == 1)
            {
                position = (donnees_ascii_affichage[C13]->m_I-minI)/(maxI-minI);
                interpBis->CalculInterpolation(systemeCouleur_OGL,
                                        lut[numBorne[C13]-1],
                                        lut[numBorne[C13]],
                                        position);
            }
            else if(AttributLut == 2)
            {
                position=
                 (donnees_ascii_affichage[C13]->m_Classe-minCl)/(maxCl-minCl);
                interpBis->CalculInterpolation(systemeCouleur_OGL,
                                        lut[numBorne[C13]-1],
                                        lut[numBorne[C13]],
                                        position);
            }
            //appelle la fonction AppliqueInterpolation
            // et stocke la couleur dans un vecteur
            couleurPoint.push_back(AppliqueInterpolation(interpBis->i_R1,
                                                        interpBis->i_V1,
                                                        interpBis->i_B1,
                                                        systemeCouleur_OGL));
            //voir TestTypeCalcul: on peux avoir rajouté un élément
            // en fin de lut. pour calculer l'interpolation de éléments
            // dont l'attribut est supérieur à la valeur de la dernière borne
            //=> on le supprime avant de passer au point suivant (nettoyage)
            if(test)
            {
                lut.pop_back();
            }
        }
    }
    break;
    default:
        wxMessageBox(_T("Il faut choisir le type d'interpolation"),
                _T("About"), wxOK | wxICON_INFORMATION, this);
    }*/
    std::cout<< "sort d'affectation couleur"<<std::endl;
}

/*--------------------------------------------------------------------------*/
/*  testTypeCalcul:  on teste quel calcul on devra effectuer                */
/*              en fonction on modifie momentanément la lut                 */
/*              on la remodifie pour revenir à la lut initiale à            */
/*              la fin de AffecteCouleur                                    */
/*--------------------------------------------------------------------------*/
/* Description : pour chaque cas, calcule l'interpolation                   */
/*--------------------------------------------------------------------------*/
bool glCanvas::TestTypeCalcul(int numBoucle,int test_Systcoul)
{
    //si la borne stockée est la borne n°0 (donc la première borne)
    //on prend la seconde borne car l'interpolation exacte se calcule
    //entre la borne n-1 et n mais elle n'utilise que les données
    //de la borne n-1
    if(numBorne[numBoucle] == 0)
    {
        numBorne[numBoucle] = 1;
    }
    else{
    }
    //si la borne stockée est la dernière borne
    //on duplique la borne comme ça on ne calcule l'interpolation
    //qu'entre 2 bornes identiques
    if(numBorne[numBoucle] == lut.size())
    {
     /* LutBound *borneCopie =new LutBound(
                        lut[numBorne[numBoucle]-1]->GetValue(),
                        lut[numBorne[numBoucle]-1]->m_color.GetC1(),
                        lut[numBorne[numBoucle]-1]->m_color.GetC2(),
                        lut[numBorne[numBoucle]-1]->m_color.GetC3(),
                        lut[numBorne[numBoucle]-1]->m_color.GetColorSpace());*/
            LutBound *borneCopie = new LutBound(*lut[numBorne[numBoucle]-1] );
            lut.push_back(borneCopie);
            return true;
    }
    //sinon
    else
    {
        //si les 2 bornes (numBorne[numBoucle]<numBorne[numBoucle]-1)
        //on les échange, il faut que les bornes soient rangées dans
        //l'ordre croissant
        if((lut[numBorne[numBoucle]]->getValue())
                <(lut[numBorne[numBoucle]-1]->getValue()))
        {
          /*  LutBound *tempEchange = new LutBound(
                                  lut[numBorne[numBoucle]-1]->GetValue(),
                                  lut[numBorne[numBoucle]-1]->m_color.GetC1(),
                                  lut[numBorne[numBoucle]-1]->m_color.GetC2(),
                                 lut[numBorne[numBoucle]-1]->m_color.GetC3(),
                        lut[numBorne[numBoucle]-1]->m_color.GetColorSpace() );*/
            LutBound *tempEchange = new LutBound(*lut[numBorne[numBoucle]-1] );
            lut[numBorne[numBoucle]] = lut[numBorne[numBoucle]-1];
            lut[numBorne[numBoucle]-1] = tempEchange;
        }
    }
}

/*--------------------------------------------------------------------------*/
/*             AppliqueInterpolation                                        */
/*--------------------------------------------------------------------------*/
/* Description : entrée: les composantes d'une couleur et le système de     */
/*                       couleur utilisé                                    */
/*               en sortie: la couleur (si le système était TSL,            */
/*              les couleurs ont été transformées en RVB,                   */
/*              pour pouvoir les afficher facilement dans OpenGL            */
/*---------------------------------------------------------------------------*/
LutColor* glCanvas::AppliqueInterpolation(int entier1,int entier2,int entier3,
                                          eLutColorSpace entier_SystCoul)
{
    LutColor color_in(entier1,entier2,entier3, entier_SystCoul);
    LutColor* color_out = new LutColor(color_in.toRGB() );

    /*int Couleur1=0, Couleur2=0, Couleur3=0;
    if(entier_SystCoul == 1)
    {
        LutColor *CouleurTSL = new LutColor(entier1,
                                        entier2,
                                        entier3,
                                        entier_SystCoul);
        CouleurTSL->TSL2RVB();
        Couleur1 = CouleurTSL->GetC1();
        Couleur2 = CouleurTSL->GetC2();
        Couleur3 = CouleurTSL->GetC3();
    }
    else
    {
        Couleur1 = entier1;
        Couleur2 = entier2;
        Couleur3 = entier3;
    }
    LutColor *couleurTemp = new LutColor(Couleur1,
                                    Couleur2,
                                    Couleur3,
                                    entier_SystCoul);*/
    return color_out;
}

BEGIN_EVENT_TABLE(glCanvas, wxGLCanvas)
    EVT_PAINT(glCanvas::OnPaint)
    EVT_SIZE(glCanvas::OnSize)
    EVT_CHAR(glCanvas::OnChar)
    EVT_MOUSE_EVENTS(glCanvas::OnMouse)
END_EVENT_TABLE()

